package cn.com.scitc.main;

import cn.com.scitc.dao.ConnDB;
import cn.com.scitc.dateFormat.DateFormat;
import cn.com.scitc.publicModule.Sample;
import cn.com.scitc.publicModule.ShowPanel;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.junit.jupiter.api.Test;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class Main extends JFrame {
    private Sample sample;
    private Connection conn;
    private String Administrators, Districts;

    private JPanel mainPanel;
    private JButton entryBtn;
    private JButton exitBtn;
    private JPanel entryReg;
    private JPanel exitReg;
    private JPanel infoReg;
    private JPanel showReg;
    private JLabel entryImage;
    private JLabel exitImage;
    private JLabel entryText;
    private JPanel infoCenterReg;
    private JLabel entryLicensePlateImg;
    private JLabel entryTime;
    private JPanel entryInfoPanel;
    private JLabel entryTimeLabel;
    private JPanel exitInfoPanel;
    private JLabel exitText;
    private JLabel exitLicensePlateImg;
    private JLabel exitTimeLabel;
    private JLabel exitTime;
    private JLabel licensePlateIn;
    private JLabel licensePlateOut;
    private JLabel entryCalcTime;
    private JLabel exitCalcTime;
    private JLabel entryClass;
    private JLabel entryStatus;
    private JLabel exitStatus;
    private JButton quitSystem;
    private JLabel Administrator;
    private JLabel District;


    public Main(String Administrator, String District) {
        this.Administrators = Administrator;
        this.Districts = District;

        conn = ConnDB.openConn();
        entryReg.setBorder(BorderFactory.createTitledBorder(BorderFactory.createRaisedBevelBorder(), "车辆入库", 0, 0, new Font("宋体", Font.PLAIN, 14), Color.lightGray));
        exitReg.setBorder(BorderFactory.createTitledBorder(BorderFactory.createRaisedBevelBorder(), "车辆入库", 0, 0, new Font("宋体", Font.PLAIN, 14), Color.lightGray));
        ImageIcon icon = new ImageIcon("src/main/java/cn/com/scitc/images/蒙A66666.jpg");
        icon.setImage(icon.getImage().getScaledInstance(500, 300, Image.SCALE_DEFAULT));
        entryImage.setIcon(icon);
        exitImage.setIcon(icon);
        entryImage.setMinimumSize(new Dimension(450, 300));

        entryText.setSize(100, 50);
        Font font = new Font("宋体", Font.PLAIN, 24);
        entryText.setFont(font);
        exitText.setFont(font);

        ImageIcon plate = new ImageIcon("src/main/java/cn/com/scitc/images/default_plate.png");
        plate.setImage(plate.getImage().getScaledInstance(327, 96, Image.SCALE_DEFAULT));
        entryLicensePlateImg.setText("");
        exitLicensePlateImg.setText("");
        entryLicensePlateImg.setIcon(plate);
        exitLicensePlateImg.setIcon(plate);
        entryLicensePlateImg.setMinimumSize(new Dimension(327, 96));
        exitLicensePlateImg.setMinimumSize(new Dimension(327, 96));
        entryLicensePlateImg.setMaximumSize(new Dimension(327, 96));
        exitLicensePlateImg.setMaximumSize(new Dimension(327, 96));


        font = new Font("宋体", Font.BOLD, 16);
        entryTimeLabel.setFont(font);
        exitTimeLabel.setFont(font);

        entryTime.setText(DateFormat.getCurrentDateTime());
        exitTime.setText(DateFormat.getCurrentDateTime());

        licensePlateIn.setBackground(Color.BLUE);
        licensePlateIn.setOpaque(true);
        licensePlateIn.setMinimumSize(new Dimension(160, 60));
        licensePlateIn.setHorizontalAlignment(SwingConstants.CENTER);
        font = new Font("宋体", Font.BOLD, 20);
        licensePlateIn.setFont(font);
        licensePlateIn.setForeground(Color.white);
        licensePlateIn.setText("蒙A66666");

        licensePlateOut.setBackground(Color.BLUE);
        licensePlateOut.setOpaque(true);
        licensePlateOut.setMinimumSize(new Dimension(160, 60));
        licensePlateOut.setHorizontalAlignment(SwingConstants.CENTER);
        font = new Font("宋体", Font.BOLD, 20);
        licensePlateOut.setFont(font);
        licensePlateOut.setForeground(Color.white);
        licensePlateOut.setText("蒙A66666");

        entryStatus.setForeground(new Color(0, 204, 102));
        exitStatus.setForeground(new Color(0, 204, 102));

        this.Administrator.setText("管理员: " + this.Administrators);
        this.District.setText("管区: " + this.Districts);

        /**
         * 入库
         */
        entryBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String licensePlate = setSample(0);
                PreparedStatement prep;
                ResultSet res;
                List<String> list = new ArrayList<>();
                try {
                    // 查询是否有预约
                    prep = conn.prepareStatement("select * from BookingWarehousing as b where b.LicensePlateNumber = ? and b.Status = 0");
                    prep.setString(1, licensePlate);
                    res = prep.executeQuery();
                    if (res.next()) {
                        list.add(res.getString("Name"));
                        list.add(res.getString("IDNumber"));
                        list.add(res.getString("MemberGrade"));
                        list.add(res.getString("BookingParking"));

                        // 有预约，将预约状态改变
                        prep = conn.prepareStatement("update BookingWarehousing as b set b.Status = 1 where b.LicensePlateNumber = ? and b.Status = 0");
                        prep.setString(1, licensePlate);
                        int count = prep.executeUpdate();
                        if (count == 1) {
                            entryClass.setText("预约入库");
                            entryStatus.setText("入库成功");
                            entryStatus.setForeground(new Color(0, 204, 102));
                        } else {
                            entryClass.setText("预约入库");
                            entryStatus.setText("入库失败");
                            entryStatus.setForeground(new Color(255, 0, 0));
                        }
                        // 将车辆出入进行信息记录
                        prep = conn.prepareStatement("insert into VehicleAccessInformation (Name,IDNumber,LicensePlateNumber,PickUpCode,MembershipLevel,MembershipDiscount,WarehousingTime,BookingParking) values(?,?,?,?,?,?,?,?)");
                        prep.setString(1, list.get(0));
                        prep.setString(2, list.get(1));
                        prep.setString(3, licensePlate);
                        prep.setString(4, String.valueOf(Math.round((Math.random() * 99999) + 10000)));
                        prep.setInt(5, Integer.parseInt(list.get(2)));
                        prep.setInt(6, 0);
                        prep.setString(7, DateFormat.getCurrentDateTime());
                        prep.setString(8, list.get(3));
                        int insertVAI = prep.executeUpdate();
                    } else {
                        // 未预约 或 预约已超时 或 临时入库车辆
                        // 查询一下，该未预约的车辆是否为会员车辆
                        prep = conn.prepareStatement("select * from MembershipInformation where LicensePlateNumber like ? ");
                        prep.setString(1, "%" + licensePlate + "%");
                        res = prep.executeQuery();
                        list.clear();
                        if (res.next()) {
                            list.add(res.getString("Name"));
                            list.add(res.getString("IDNumber"));
                            list.add(res.getString("Grade"));
                        }
                        prep = conn.prepareStatement("insert into VehicleAccessInformation (Name,IDNumber,LicensePlateNumber,PickUpCode,MembershipLevel,MembershipDiscount,WarehousingTime,BookingParking) values(?,?,?,?,?,?,?,?)");

                        PreparedStatement pre;
                        // 若用户没有预约，就根据当前用户进入的库进行随机分配
                        pre = conn.prepareStatement("select * from LdleParking where CubeLibraryNumber = ? and Region = ? and Arrangement = ?");
                        String[] split = Districts.split("-");

                        pre.setString(1, split[0] + "-" + split[1]);
                        pre.setString(2, split[2]);
                        int[] Arrangement = {1, 2, 3, 4, 5};
                        int selectArrangement = Arrangement[(int) Math.round(Math.random() * 4)];
                        pre.setInt(3, selectArrangement);
                        res = pre.executeQuery();
                        List<String> ldldList = new ArrayList<>();
                        if (res.next()) {
                            ldldList.add(res.getString("AutoNumber"));
                            ldldList.add(res.getString("Number"));
                        }

                        JSONArray jsonArray = JSONArray.parseArray(ldldList.get(1));
                        String parkingInfo = Districts + "-" + String.valueOf(selectArrangement) + "-" + jsonArray.get(0);
                        jsonArray.remove(0);
                        pre = conn.prepareStatement("update LdleParking set Number = ? where AutoNumber = ?");
                        pre.setString(1, JSON.toJSONString(jsonArray));
                        pre.setInt(2, Integer.parseInt(ldldList.get(0)));
                        pre.executeUpdate();

                        if (list.size() != 0) {
                            prep.setString(1, list.get(0));
                            prep.setString(2, list.get(1));
                            prep.setInt(5, Integer.parseInt(list.get(2)));
                        } else {
                            prep.setString(1, "未知");
                            prep.setString(2, "未知");
                            prep.setInt(5, 0);
                        }
                        prep.setString(8, parkingInfo);
                        prep.setString(3, licensePlate);
                        prep.setString(4, String.valueOf(Math.round((Math.random() * 99999) + 10000)));

                        prep.setInt(6, 0);
                        prep.setString(7, DateFormat.getCurrentDateTime());
                        int insertVAI = prep.executeUpdate();
                        if (insertVAI == 1) {
                            entryClass.setText("临时入库");
                            entryStatus.setText("入库成功");
                            entryStatus.setForeground(new Color(0, 204, 102));
                        } else {
                            entryClass.setText("临时入库");
                            entryStatus.setText("入库失败");
                            entryStatus.setForeground(new Color(255, 0, 0));
                        }
                    }

                } catch (SQLException e1) {
                    e1.printStackTrace();
                }
            }
        });

        /**
         * 出库
         */
        exitBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String licensePlate = setSample(1);
                PreparedStatement prep;
                ResultSet res;
                try {

                    /**
                     * 更新预约记录信息
                     */
                    prep = conn.prepareStatement("update BookingWarehousing set Status = 2 where LicensePlateNumber = ? and Status = 1");
                    prep.setString(1, licensePlate);
                    prep.executeUpdate();

                    /**
                     * 根据车牌号查询未出库的车辆出入信息
                     */

                    prep = conn.prepareStatement("select * from VehicleAccessInformation where LicensePlateNumber = ? and OutgoingTime is NULL");
                    prep.setString(1, licensePlate);
                    res = prep.executeQuery();
                    List<String> parkingString = new ArrayList<>();
                    if (res.next()) {
                        parkingString.add(res.getString("BookingParking"));
                    }

                    /**
                     * -----------车位释放-----------
                     */
                    // 车位分解
                    String[] parking = parkingString.get(0).split("-");
                    // 立方库编号
                    String libraryNumber = parking[0] + "-" + parking[1];
                    // 区域
                    String region = parking[2];
                    // 楼层
                    int arrangement = Integer.valueOf(parking[3]);
                    prep = conn.prepareStatement("select * from LdleParking where CubeLibraryNumber = ? and Region = ? and Arrangement = ?");
                    prep.setString(1, libraryNumber);
                    prep.setString(2, region);
                    prep.setInt(3, arrangement);
                    res = prep.executeQuery();
                    List<String> list = new ArrayList<>();
                    if (res.next()) {
                        list.add(res.getString("AutoNumber"));
                        list.add(res.getString("Number"));
                    }
                    JSONArray jsonArray = JSONArray.parseArray(list.get(1));
                    jsonArray.add(Integer.parseInt(parking[4]));
                    String toJSONString = JSON.toJSONString(jsonArray);

                    prep = conn.prepareStatement("update LdleParking set Number = ? where AutoNumber = ?");
                    prep.setString(1, toJSONString);
                    prep.setInt(2, Integer.parseInt(list.get(0)));
                    prep.executeUpdate();

                    /**
                     * 更新车辆出入记录信息
                     */
                    prep = conn.prepareStatement("update VehicleAccessInformation set OutgoingTime = ? where LicensePlateNumber = ? and OutgoingTime is NULL");
                    prep.setString(1, DateFormat.getCurrentDateTime());
                    prep.setString(2, licensePlate);
                    int updateOutgoingTime = prep.executeUpdate();
                    if (updateOutgoingTime == 1) {
                        exitStatus.setText("出库成功");
                        exitStatus.setForeground(new Color(0, 204, 102));
                    } else {
                        exitStatus.setText("出库失败");
                        exitStatus.setForeground(new Color(255, 0, 0));
                    }

                } catch (SQLException e1) {
                    e1.printStackTrace();
                }
            }
        });

        /**
         * 退出
         */
        quitSystem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int rc = JOptionPane.showConfirmDialog(null, "你确定要退出系统吗？", "立方库智能停车管理系统", JOptionPane.YES_NO_OPTION);
                if (rc == 0) {
                    System.exit(0);
                }
            }
        });

        new ShowPanel(this, mainPanel);
        setMinimumSize(new Dimension(700, 460));

    }

    /**
     * 车牌识别
     *
     * @param inOut
     * @return
     */
    private String setSample(int inOut) {
        long startTime = Long.parseLong(DateFormat.getCurrentTimeMillis());

        /**
         * 获取车牌识别结果
         */
        sample = new Sample();
        String[] sample = Main.this.sample.Sample();
        if (sample.length == 0){return "";}
        long endTime = Long.parseLong(DateFormat.getCurrentTimeMillis());

        /**
         * 读取图像
         */
        ImageIcon icon = new ImageIcon(sample[0].toString());
        icon.setImage(icon.getImage().getScaledInstance(500, 300, Image.SCALE_DEFAULT));

        /**
         * 设置显示图像
         */
        if (inOut == 0) {
            entryImage.setIcon(icon);
        } else {
            exitImage.setIcon(icon);
        }

        /**
         * 解析车牌识别结果，提取车牌号及车牌色
         */
        JSONObject jsonObject = JSONObject.parseObject(sample[1].toString());
        JSONObject jsonObject1 = JSONObject.parseObject(jsonObject.getString("words_result"));

        /**
         * 设置当前入库时间 或 出库时间
         */
        if (inOut == 0) {
            entryTime.setText(DateFormat.getCurrentDateTime());
        } else {
            exitTime.setText(DateFormat.getCurrentDateTime());
        }

        /**
         * 设置显示车牌号
         */
        if (inOut == 0) {
            licensePlateIn.setText(jsonObject1.getString("number"));
        } else {
            licensePlateOut.setText(jsonObject1.getString("number"));
        }

        /**
         * 设置显示车牌号的背景样式及车牌号颜色
         */
        switch (jsonObject1.getString("color")) {
            case "blue":
                if (inOut == 0) {
                    licensePlateIn.setBackground(new Color(0, 0, 255));
                    licensePlateIn.setForeground(Color.white);
                } else {
                    licensePlateOut.setBackground(new Color(0, 0, 255));
                    licensePlateOut.setForeground(Color.white);
                }
                break;
            case "green":
                if (inOut == 0) {
                    licensePlateIn.setBackground(new Color(0, 255, 0));
                    licensePlateIn.setForeground(Color.black);
                } else {
                    licensePlateOut.setBackground(new Color(0, 255, 0));
                    licensePlateOut.setForeground(Color.black);
                }
                break;
            case "yellow":
                if (inOut == 0) {
                    licensePlateIn.setBackground(new Color(255, 255, 0));
                    licensePlateIn.setForeground(Color.black);
                } else {
                    licensePlateOut.setBackground(new Color(255, 255, 0));
                    licensePlateOut.setForeground(Color.black);
                }
                break;
            default:
                if (inOut == 0) {
                    licensePlateIn.setBackground(new Color(255, 255, 255));
                    licensePlateIn.setForeground(Color.black);
                } else {
                    licensePlateOut.setBackground(new Color(255, 255, 255));
                    licensePlateOut.setForeground(Color.black);
                }
                break;
        }

        try {
            /**
             * 读取图像 进入图像的裁剪
             */
            BufferedImage bi = ImageIO.read(new File(sample[0]));
            String vertexeslocation = jsonObject1.getString("vertexes_location");
            JSONArray jsonArray = JSONArray.parseArray(vertexeslocation);

            JSONObject leftTopPoint = JSONObject.parseObject(jsonArray.get(0).toString());
            JSONObject rightBottomPoint = JSONObject.parseObject(jsonArray.get(2).toString());
            int xPoint = Integer.parseInt(leftTopPoint.getString("x"));
            int yPoint = Integer.parseInt(leftTopPoint.getString("y"));
            int width = Integer.parseInt(rightBottomPoint.getString("x")) - xPoint;
            int height = Integer.parseInt(rightBottomPoint.getString("y")) - yPoint;

            BufferedImage subimage = bi.getSubimage(xPoint, yPoint, width, height);
            ImageIcon plate = new ImageIcon(subimage);
            plate.setImage(plate.getImage().getScaledInstance(327, 96, Image.SCALE_DEFAULT));
            if (inOut == 0) {
                entryLicensePlateImg.setIcon(plate);
            } else {
                exitLicensePlateImg.setIcon(plate);
            }
        } catch (IOException e1) {
            e1.printStackTrace();
        }

        long res = endTime - startTime;

        if (inOut == 0) {
            entryCalcTime.setText(String.valueOf(res) + "ms");
        } else {
            exitCalcTime.setText(String.valueOf(res) + "ms");
        }
        return jsonObject1.getString("number");
    }

    private void createUIComponents() {
        // TODO: place custom component creation code here
    }
}
